/*
 * @Author: yangzonglong
 * @Date: 2021-05-13 16:15:57
 * @version: v1.0.0
 * @Descripttion: 用户节点设置
 * @LastEditors: 871387321@qq.com 871387321@qq.com
 * @LastEditTime: 2023-11-09 16:38:55
 * @Auditor: 
 */
import React, { useState, useContext, useEffect, useCallback, useRef, useMemo } from 'react';
import { Form, Input, Select as AntdSelect, Checkbox, Radio } from 'antd';
import { Select, BtnUpload } from '@library';
import UserInput from '@library/components/formx/extra/UserInput';
import UserProps from '@library/interface/userInfo';
import ModalTableInModelInput from '@library/components/formx/extra/ModalTableInModelInput';
import context from '../context';
import EditEmailModal from './_EditEmailModal';
import { getUsers, getEmailTemplate } from './../Api';
import { BPMN_NODE_TYPE, createBpmnXMLNode } from './../../../utils/bpmnUtils';
import Strategy from '../strategy/_Strategy';
import { UserTaskSelfProps, FormField, StartEventSelfProps } from './../../../interface';
import style from './../style.module.scss';

const T = window.$app.t;
const FormItem = Form.Item;
const fieldNames = { label: 'codeDesc', value: 'codeValue' };

const nodeTypeQuery = {
  where: { code: 'WFL_NODE_TYPE' },
  include: [{ model: "CompanyCodeValue" }]
};

const userAssignQuery = {
  where: { code: 'WFL_NODE_USERASSIGN_RULE' },
  include: [{ model: "CompanyCodeValue" }]
};

const rtnDataAfter = (data: any) => {
  return data.CompanyCodeValues;
};

const positionModel = {
  title: '选择岗位',
  url: '/bk/mid/organization/getPositionBeAssgined',
  fieldNames: { label: 'positionName', value: 'positionCode' },
  searchFields: ['positionCode', 'positionName', 'deptName'],
  searchFieldsText: ['岗位编码', '岗位描述', '部门'],
  columns: [
    { title: '岗位编码', dataIndex: 'positionCode' },
    { title: '岗位描述', dataIndex: 'positionName' },
    { title: '部门', dataIndex: 'deptName' },
    {
      title: '用户',
      dataIndex: 'EmployeeAssigns',
      tooltip: true,
      ellipsis: true,
      render: (employeeAssigns: any[]) => {
        return employeeAssigns.map(item => item.userName).join(',');
      }
    }
  ]
};

const spModel = {
  title: '选择审批邮件模版',
  url: '/bk/api/workflow/EmailTemplate/find',
  fieldNames: { label: 'templateName', value: 'templateCode' },
  searchFields: ['templateCode', 'templateName'],
  searchFieldsText: ['模版编号', '模版名称'],
  columns: [
    { title: '模版编号', dataIndex: 'templateCode' },
    { title: '模版名称', dataIndex: 'templateName' },
  ]
};

export default () => {
  const isInit = useRef(false);
  const emailModalRef = useRef<any>();
  const { self, modeler } = useContext(context);
  const [taskName, setTaskName] = useState('');

  const [emailTemplateCode, setEmailTemplateCode] = useState(''); // 会签 或 会签
  const [emailTemplateName, setEmailTemplateName] = useState(''); // 会签 或 会签
  const [approvalTypeCode, setApprovalTypeCode] = useState(''); // 会签 或 会签
  const [approvalTypeName, setApprovalTypeName] = useState('');
  const [assignStrategy, setAssignStrategy] = useState(''); //分配策略
  const [assignValue, setAssignValue] = useState<string[] | string>([]); // 指定人员
  const [assignDesc, setAssignDesc] = useState<string[] | string>([]);
  const [defSlectedUsers, setDefSlectedUsers] = useState<UserProps[]>([]); // 已选择用户
  const [approvalDistinct, setApprovalDistinct] = useState(''); // 审批人去重
  const [enableEmailNotification, setEnableEmailNotification] = useState(false); // 设置为true时审批人将在到自己审批时收到审批的邮件, 反之不会收到邮件
  const [informTitle, setInformTitle] = useState<string | undefined>(''); // 邮件
  const [informContent, setInformContent] = useState<string | undefined>(''); //邮件
  const [vars, setVars] = useState<FormField[]>([]);
  const [errorHandlingCode, setErrorHandlingCode] = useState('10'); // 节点异常报错
  const [ccApplicant, setCcApplicant] = useState(false);
  const [enableTransferEmailNotification, setEnableTransferEmailNotification] = useState(false);
  const [enableCountersignEmailNotification, setEnableCountersignEmailNotification] = useState(false);
  const [pdfAttachmentPathFlag, setPdfAttachmentPathFlag] = useState(false);
  const [pdfAttachments, setPdfAttachments] = useState<any[]>([]);
  const [ccStrategy, setCcStrategy] = useState('');
  const [ccUserList, setCcUserList] = useState<Array<{ id: string; name: string; }>>([]);
  const _self = self as UserTaskSelfProps;

  const changeTaskName = useCallback((e: React.BaseSyntheticEvent) => setTaskName(e.target.value), []);

  const changeTemplateType = useCallback((e: any, v: any) => {
    setEmailTemplateCode(e?.value);
    setEmailTemplateName(e?.label);
    setInformContent(v?.content || '');
    setInformTitle(v?.title || '');
  }, []);

  const changeApprovalType = useCallback((e: any) => {
    setApprovalTypeCode(e.value);
    setApprovalTypeName(e.label);
  }, []);

  const changeAssignStrategy = useCallback((e: any) => {
    setAssignStrategy(e.value);
    setAssignValue('');
    setAssignDesc('');

    // 指定人员
    if (e.value === 'assignee') {
      setApprovalDistinct('');
    }
  }, []);

  // 改变抄送人
  const changeCcStrategy = useCallback((data: any) => {
    if (!isInit.current) return;

    setCcStrategy(data.assignStrategy);

    let assignValue = '';
    if (typeof data.assignValue === 'string') assignValue = data.assignValue;
    if (Array.isArray(data.assignValue)) assignValue = data.assignValue[0];

    modeler.get('modeling').updateProperties(_self, {
      ccStrategy: data.assignStrategy,
      ccValue: assignValue
    });

    if (data.assignValue) {
      const assignValue = Array.isArray(data.assignValue) ? data.assignValue : [data.assignValue];

      _self.businessObject!.extensionElements = Object.assign(createBpmnXMLNode(modeler, BPMN_NODE_TYPE.EXTENSION_ELEMENTS), {
        values: [
          _self.businessObject!.extensionElements?.values?.[0],
          Object.assign(createBpmnXMLNode(modeler, BPMN_NODE_TYPE.HL_CC_USER_LIST), {
            values: assignValue.map((id: string, index: number) => {
              const name = data.assignDesc[index];
              return Object.assign(createBpmnXMLNode(modeler, BPMN_NODE_TYPE.HL_USER), { id, name });
            })
          })
        ]
      });
    }
  }, []);

  const changeAssignee = useCallback((value: string, label: string, rows: UserProps[]) => {
    setAssignValue(rows.map(item => item.id));
    setAssignDesc(rows.map(item => item.name));
    setDefSlectedUsers(rows);
  }, []);

  // 改变表单来源
  const changeFormSouce = useCallback((e: any) => {
    const curr = vars.find(item => item.fieldName === e);
    setAssignValue(e);
    setAssignDesc(curr?.name || '');
  }, [vars]);

  // 改变岗位
  const changePosition = useCallback((value: string, id: string, rows: any[]) => {
    setAssignValue(rows.map(item => item.positionCode));
    setAssignDesc(rows.map(item => item.positionName));
  }, []);

  // 改变岗位
  const changeSp = useCallback((value: string, id: string, rows: any[]) => {
    const e = rows?.[0] || {};
    setEmailTemplateCode(e?.templateCode);
    setEmailTemplateName(e?.templateName);
    setInformContent(e?.content || '');
    setInformTitle(e?.title || '');
  }, []);

  const onChangeEnableEmailNotification = useCallback((e) => {
    setEnableEmailNotification(e.target.checked);
    if (e.target.checked) {
      setCcApplicant(true);
      setEnableTransferEmailNotification(true);
      setEnableCountersignEmailNotification(true);
    }
  }, []);


  useEffect(() => {
    if (informTitle === undefined && informContent === undefined) {
      getEmailTemplate().then(res => {
        setInformContent(prev => prev || ((res?.rows?.[0] || {}).content));
        setInformTitle(prev => prev || ((res?.rows?.[0] || {}).title));
      });
    }
  }, [informTitle, informContent]);


  useEffect(() => {
    const rootChildren = _self.parent?.children || [];
    const startEvent = rootChildren.find((item) => item.type === BPMN_NODE_TYPE.START_EVENT) as StartEventSelfProps;
    const globalVar: any = startEvent?.businessObject?.extensionElements?.values?.[0].values || [];

    const assignValue = _self.businessObject?.assignValue || [];
    const assignDesc = _self.businessObject?.assignDesc || [];
    setTaskName(_self.businessObject?.name || '');
    setEmailTemplateCode(_self.businessObject?.emailTemplateCode || '');
    setApprovalTypeCode(_self.businessObject?.approvalTypeCode || '');
    setApprovalTypeName(_self.businessObject?.approvalTypeName || '');
    setAssignStrategy(_self.businessObject?.assignStrategy || '');
    setAssignValue(_self.businessObject?.assignStrategy !== 'script' && typeof assignValue === 'string' ? assignValue.split(',') : assignValue);
    setAssignDesc(typeof assignDesc === 'string' ? assignDesc.split(',') : assignDesc);
    setApprovalDistinct(_self.businessObject?.approvalDistinct || '');

    setInformTitle(_self.businessObject?.informTitle || undefined);
    setInformContent(_self.businessObject?.informContent || undefined);
    setEnableEmailNotification(_self.businessObject?.enableEmailNotification || false);
    setErrorHandlingCode(_self.businessObject?.errorHandlingCode || '10');
    setCcApplicant(_self.businessObject?.ccApplicant === false ? false : true);
    setEnableTransferEmailNotification(_self.businessObject?.enableTransferEmailNotification === false ? false : true);
    setEnableCountersignEmailNotification(_self.businessObject?.enableCountersignEmailNotification === false ? false : true);

    setCcStrategy(_self.businessObject?.ccStrategy || '');
    setCcUserList((_self.businessObject?.extensionElements?.values?.[1]?.values as any) || []);

    console.log(_self.businessObject, 'self.businessObject');

    if (_self.businessObject?.pdfAttachmentPath) {
      setPdfAttachmentPathFlag(true);
      setPdfAttachments([{
        status: 'done',
        name: _self.businessObject?.pdfAttachmentName,
        url: _self.businessObject?.pdfAttachmentPath,
        response: {
          originalname: _self.businessObject?.pdfAttachmentName,
          filename: _self.businessObject?.pdfAttachmentPath
        }
      }]);
    }

    setVars(globalVar.map((item: any) => ({ ...item })));
    setDefSlectedUsers([]);

    setTimeout(() => isInit.current = true, 500);
  }, [_self]);


  useEffect(() => {
    // 指定人员
    if (Array.isArray(assignValue) && assignValue.length && assignStrategy === 'assignee') {
      getUsers(assignValue).then(result => {
        if (result) setDefSlectedUsers(result);
      });
    }
  }, [assignValue, assignStrategy]);

  useEffect(() => {
    if (!isInit.current) return;

    modeler.get('modeling').updateProperties(_self, {
      name: taskName,
      approvalTypeCode,
      approvalTypeName,
      assignStrategy,
      assignValue,
      assignDesc,
      approvalDistinct,
      enableEmailNotification,
      informTitle,
      informContent,
      emailTemplateCode,
      emailTemplateName,
      errorHandlingCode,
      ccApplicant: !enableEmailNotification ? false : ccApplicant,
      enableTransferEmailNotification: !enableEmailNotification ? false : enableTransferEmailNotification,
      enableCountersignEmailNotification: !enableEmailNotification ? false : enableCountersignEmailNotification,
      pdfAttachmentPath: pdfAttachments.length ? pdfAttachments[0]?.response?.filename : '',
      pdfAttachmentName: pdfAttachments.length ? pdfAttachments[0]?.response?.originalname : ''
    });
  }, [_self, modeler, taskName, approvalTypeCode, approvalTypeName, assignStrategy, assignValue, assignDesc, approvalDistinct, enableEmailNotification, errorHandlingCode, informTitle, informContent, ccApplicant, enableTransferEmailNotification, enableCountersignEmailNotification, emailTemplateCode, emailTemplateName, pdfAttachments]);

  const ccStrategyData = useMemo(() => ({
    assignStrategy: ccStrategy,
    assignValue: ccUserList.map(item => item.id)
  }), [ccStrategy]);

  return (
    <>
      <Form layout='vertical'>
        <p>{T('baseSet')}</p>

        <FormItem label={T('numberID')}>
          <Input disabled value={_self.businessObject?.id} />
        </FormItem>
        <FormItem label={T('taskName')} required>
          <Input value={taskName} onChange={changeTaskName} />
        </FormItem>

        <FormItem label={T('auditType')} required>
          <Select
            onChange={changeApprovalType}
            query={nodeTypeQuery}
            value={approvalTypeCode}
            fieldNames={fieldNames}
            rtnDataAfter={rtnDataAfter}
            url='/bk/api/company/CompanyCode/findOne' />
        </FormItem>

        <FormItem label={T('errorHandling')} required>
          <Radio.Group value={errorHandlingCode} onChange={e => setErrorHandlingCode(e.target.value)}>
            <Radio value={'10'}>{T('errorReport')}</Radio>
            <Radio value={'20'}>{T('historyPass')}</Radio>
            <Radio value={'30'}>{T('historyRefuse')}</Radio>
          </Radio.Group>
        </FormItem>

        <div className={style.dividingLine}></div>
        <p>{T('distStrategy')}</p>

        <FormItem label={T('distStrategy')} required>
          <Select
            onChange={changeAssignStrategy}
            query={userAssignQuery}
            value={assignStrategy}
            fieldNames={fieldNames}
            rtnDataAfter={rtnDataAfter}
            url='/bk/api/company/CompanyCode/findOne' />
        </FormItem>

        {assignStrategy === 'script' && (
          <>
            <FormItem label={T('scriptSet')} required>
              <Input.TextArea
                onChange={e => setAssignValue(e.target.value)}
                value={assignValue}
                rows={6} />
            </FormItem>
          </>
        )}

        {assignStrategy === 'assignee' && (
          <>
            <FormItem label={T('designatedUser')} required>
              <UserInput
                extraInitialValue={defSlectedUsers}
                rowSelectionType='checkbox'
                id='assignee'
                value={Array.isArray(assignDesc) ? assignDesc.join(',') : assignDesc}
                onChange={changeAssignee} />
            </FormItem>
          </>
        )}

        <FormItem label={T('approverDuplication')}>
          <AntdSelect value={approvalDistinct} onChange={setApprovalDistinct} allowClear>
            <AntdSelect.Option value={'10'}>
              {T('approvalDistinct')}
            </AntdSelect.Option>
          </AntdSelect>
        </FormItem>

        {assignStrategy === 'position' && (
          <FormItem label={T('appointPos')} required>
            <ModalTableInModelInput
              rowSelectionType='radio'
              placeholder={T('positionPlaceholder')}
              id=''
              value={Array.isArray(assignValue) ? assignValue[0] : ''}
              model={positionModel}
              onChange={changePosition} />
          </FormItem>
        )}

        {assignStrategy === 'formSource' && (
          <FormItem label={T('formSource')} required>
            <AntdSelect
              value={assignValue}
              allowClear
              onChange={changeFormSouce}>
              {vars.map(item => (
                <AntdSelect.Option value={item.fieldName}>{item.name}</AntdSelect.Option>
              ))}
            </AntdSelect>
          </FormItem>
        )}

        <FormItem label={T('enableEmailNotification')} className={style.antdFormItemRow}>
          <Checkbox
            checked={enableEmailNotification}
            onChange={onChangeEnableEmailNotification} />
        </FormItem>


        {enableEmailNotification && (
          <FormItem label={T('enableTransferEmailNotification')} className={style.antdFormItemRow}>
            <Checkbox
              checked={enableTransferEmailNotification}
              onChange={e => setEnableTransferEmailNotification(e.target.checked)} />
          </FormItem>
        )}

        {enableEmailNotification && (
          <FormItem label={T('enableCountersignEmailNotification')} className={style.antdFormItemRow}>
            <Checkbox
              checked={enableCountersignEmailNotification}
              onChange={e => setEnableCountersignEmailNotification(e.target.checked)} />
          </FormItem>
        )}

        {enableEmailNotification && (
          <FormItem label={T('ccApplicant')} className={style.antdFormItemRow}>
            <Checkbox
              checked={ccApplicant}
              onChange={e => setCcApplicant(e.target.checked)} />
          </FormItem>
        )}

        {
          enableEmailNotification && <FormItem label={T('enableEmailTemp')} >

            <ModalTableInModelInput
              allowClear
              rowSelectionType='radio'
              placeholder={T('pleaseSelect') + T('enableEmailTemp')}
              id=''
              value={emailTemplateCode || ''}
              model={spModel}
              onChange={changeSp} />

            {/* <Select
              onChange={changeTemplateType}
              placeholder={T('pleaseSelect') + T('enableEmailTemp')}
              value={emailTemplateCode || undefined}
              fieldNames={{ label: 'templateName', value: 'templateCode' }}
              url='/bk/api/workflow/EmailTemplate/find' /> */}
          </FormItem>
        }

        <Strategy
          label={window.$app.t('cc')}
          required={false}
          defData={ccStrategyData}
          onChange={changeCcStrategy}
          vars={vars} />

        {/* {enableEmailNotification && <>
          <FormItem label={T('邮件标题')}>
            <Input value={informTitle}
              onChange={e => setInformTitle(e.target.value)}
              placeholder='请输入固定文字和变量' />
          </FormItem>
          <FormItem label={T('邮件正文')}>
            <Input onClick={() => {
              emailModalRef.current?.setData({
                informContent
              });
            }} readOnly value={informContent} suffix={<Icon onClick={() => {
              emailModalRef.current?.setData({
                informContent
              });
            }} style={{ color: "#DEDEDF" }} icon="&#xe63b;" />} />
          </FormItem>
        </>
        } */}

        <EditEmailModal ref={emailModalRef} onSave={(v: any) => {
          setInformContent(v.informContent);
          // setInformTitle(v.informContent);
        }} />

        <FormItem label={T('createFile')} className={style.antdFormItemRow}>
          <Checkbox
            checked={pdfAttachmentPathFlag}
            onChange={e => {
              setPdfAttachmentPathFlag(e.target.checked);
              setPdfAttachments([]);
            }} />
        </FormItem>

        {pdfAttachmentPathFlag && (
          <FormItem required label={T('fileTemp')} className={style.antdFormItemRow}>
            <BtnUpload
              only
              accept='.html'
              fileList={pdfAttachments}
              onChange={({ fileList }) => {
                setPdfAttachments(fileList);
              }}
              onDelete={() => setPdfAttachments([])} />
          </FormItem>
        )}
      </Form>
    </>
  );
};
